package cn.skyquant.quant4j.jforex.sdk.util;

import cn.skyquant.quant4j.api.quant.Bar;
import cn.skyquant.quant4j.api.quant.Tick;
import cn.skyquant.quant4j.api.quant.TimeBar;
import cn.skyquant.quant4j.api.ylzc.YlzcDTO;
import cn.skyquant.quant4j.api.ylzc.YlzcMap;
import cn.skyquant.quant4j.api.ylzc.ZigZag;
import cn.skyquant.quant4j.jforex.sdk.strategy.Boll;
import cn.skyquant.quant4j.jforex.sdk.strategy.MA;
import cn.skyquant.quant4j.jforex.sdk.strategy.TimeBoll;
import cn.skyquant.quant4j.sdk.enums.TradeDirection;
import cn.skyquant.quant4j.sdk.enums.YlzcType;
import com.dukascopy.api.IBar;
import com.dukascopy.api.IEngine;
import com.dukascopy.api.ITick;
import com.dukascopy.api.Instrument;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

public final class QuantUtil {

    public static final boolean isMatch(TradeDirection td, IEngine.OrderCommand orderCommand) {
        if (td == TradeDirection.LONG && orderCommand == IEngine.OrderCommand.BUY) {
            return true;
        }
        if (td == TradeDirection.SHORT && orderCommand == IEngine.OrderCommand.SELL) {
            return true;
        }
        return false;
    }

    public static final TimeBar convertIBarToTimeBar(IBar ibar) {
        return new TimeBar(ibar.getOpen(), ibar.getClose(), ibar.getHigh(), ibar.getLow(), ibar.getVolume(), ibar.getTime());
    }

    public static final List<TimeBar> batchConvertIBarToTimeBar(List<IBar> ibarList) {
        return ibarList.stream().map(x -> convertIBarToTimeBar(x)).collect(Collectors.toList());
    }

    public static final List<MA> batchConvertDoubleToMA(double[] mas, List<TimeBar> timeBarList) {
        List<MA> maList = new ArrayList<>();
        if (mas.length != timeBarList.size()) {
            return maList;
        }
        for (int i = 0; i < mas.length; i++) {
            TimeBar timeBar = timeBarList.get(i);
            maList.add(new MA(i,timeBar.time,mas[i]));
        }
        return maList;
    }

    public static final List<ZigZag> batchConvertZigZagToYlzc(double[] zigzags, List<TimeBar> barList) {
        List<ZigZag> ylzcList = new ArrayList<>();
        for (int i = 0; i < zigzags.length; i++) {
            if (!Double.isNaN(zigzags[i])) {
                TimeBar timeBar = barList.get(i);

                YlzcType type = null;
                if (timeBar.high == zigzags[i]) {
                    type = YlzcType.Y;
                }
                if (timeBar.low == zigzags[i]) {
                    type = YlzcType.Z;
                }
                double h_diff = Math.abs(timeBar.high - zigzags[i]) / zigzags[i];
                double l_diff = Math.abs(timeBar.low - zigzags[i]) / zigzags[i];
                if (type == null &&
                        timeBar.high != zigzags[i]
                        && timeBar.low != zigzags[i]
                        && h_diff < l_diff) {
                    type = YlzcType.Y;
                }
                if (type == null && timeBar.high != zigzags[i]
                        && timeBar.low != zigzags[i]
                        && h_diff > l_diff) {
                    type = YlzcType.Z;
                }
                if (type != null) {
                    ylzcList.add(new ZigZag(type, zigzags[i], timeBar.time, i));
                }
            }
        }
        return ylzcList;
    }

    public static final Bar convertIBarToBar(IBar ibar) {
        return new Bar(ibar.getOpen(), ibar.getClose(), ibar.getHigh(), ibar.getLow(), ibar.getVolume());
    }

    public static final List<Bar> batchConvertIBarToBar(List<IBar> ibarList) {
        return ibarList.stream().map(x -> convertIBarToBar(x)).collect(Collectors.toList());
    }

    public static final Tick convertITickToTick(Instrument instrument, ITick tick) {
        return new Tick(instrument.name(), tick.getAsk(), tick.getAsks(), tick.getBid(), tick.getBids(), tick.getAskVolume(), tick.getAskVolumes(), tick.getBidVolume(), tick.getBidVolumes());
    }

    public static final List<Tick> batchConvertITickToTick(Instrument instrument, List<ITick> tickList) {
        return tickList.stream().map(x -> convertITickToTick(instrument, x)).collect(Collectors.toList());
    }

}
